package org.adream.account.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * AES 文本加密工具
 */
public class AESUtils {

    // Base64
    private static final Base64.Decoder decoder = Base64.getDecoder();
    private static final Base64.Encoder encoder = Base64.getEncoder();
    private static final String KEY_ALGORITHM = "AES";
    //默认的加密算法
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    // 生成密钥对象
    private static SecretKey generateKey(byte[] key) throws Exception {
        // 指定的RNG算法名称, 创建安全随机数生成器
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        //设置加密用的种子，密钥
        random.setSeed(key);
        // 创建AES算法生成器
        KeyGenerator gen = KeyGenerator.getInstance(KEY_ALGORITHM);
        // 初始化算法生成器
        gen.init(128, random);
        // 生成 AES密钥对象
        return gen.generateKey();
    }

    /**
     * 数据加密
     *
     * @param plainStr 明文字符串
     * @param key      秘钥
     * @return 密文字符串
     * @throws Exception
     */
    public static String encrypt(String plainStr, String key) throws Exception {
        SecretKey secKey = generateKey(key.getBytes(StandardCharsets.UTF_8));
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secKey);
        byte[] encryptByte = cipher.doFinal(plainStr.getBytes(StandardCharsets.UTF_8));
        return encoder.encodeToString(encryptByte);
    }

    /**
     * 数据解密
     *
     * @param cipherStr 密文字符串
     * @param key       秘钥
     * @return 明文字符串
     * @throws Exception
     */
    public static String decrypt(String cipherStr, String key) throws Exception {
        SecretKey secKey = generateKey(key.getBytes(StandardCharsets.UTF_8));
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secKey);
        byte[] decryptByte = cipher.doFinal(decoder.decode(cipherStr));
        return new String(decryptByte, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        String content = "用户数据"; // 任意用户数据
        String key = "key"; // 秘钥 可以是用户的uid，也可以是其他配置的东西...
        String cipher = AESUtils.encrypt(content, key);
        System.out.println(cipher);
        String plain = AESUtils.decrypt(cipher, key);
        System.out.println(plain);
    }

}
